# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: xguo

import sys
import json
import os
import pathlib
import tempfile

# import invoke

from absl import app, flags

FLAGS = flags.FLAGS

flags.DEFINE_string('exchange', None, 'Specify exchange.')

flags.DEFINE_boolean('gdb', False, 'Use gdb or not!')


def parse_unique_symbol(unique_symbol):
  return unique_symbol.split(':')


def get_recipe(mea_str):
  mea_str = mea_str.replace('.', '_').lower()
  start_find = False
  has_realtime = False
  has_snapshot = False
  has_incremental = False
  with open('data/coin2/feed/subscribers.toml') as f:
    for line in f.readlines():
      if mea_str in line:
        start_find = True
      if start_find:
        if "recipes.realtime " in line:
          has_realtime = True
        if "recipes.snapshot " in line:
          has_snapshot = True
        if "recipes.incremental " in line:
          has_incremental = True
        if line == "" or line == "\r" or line == "\n":
          break
  if has_realtime:
    return "realtime"
  if has_snapshot:
    return "snapshot"
  return "incremental"


def convert_to_app_config(strat):
  key_path = pathlib.Path.home().joinpath('config').joinpath(strat["key_filepath"]).as_posix()
  strategy_name = strat["strategy_name"]
  if "strategy_group" in strat:
    strategy_group = strat["strategy_group"]
  else:
    strategy_group = "simple_mm"

  data = {}
  data["feed"] = {}
  data["order"] = {}

  trade_mea = strat["mea"]
  ref_mea = strat["ref_mea"]
  data["feed"]["exchanges"] = {}
  data["feed"]["exchanges"][trade_mea] = {}
  data["feed"]["exchanges"][trade_mea]["mea"] = trade_mea
  data["feed"]["exchanges"][trade_mea]["type"] = "FEED_SYSTEM_TYPE_LIVE"
  data["feed"]["exchanges"][trade_mea]["products"] = {}
  data["feed"]["exchanges"][trade_mea]["websocket"] = {"num_workers": 1}
  data["feed"]["exchanges"][trade_mea]["products"]["norms"] = []
  data["feed"]["exchanges"][trade_mea]["recipe"] = get_recipe(trade_mea)

  data["feed"]["exchanges"][ref_mea] = {}
  data["feed"]["exchanges"][ref_mea]["mea"] = ref_mea
  data["feed"]["exchanges"][ref_mea]["type"] = "FEED_SYSTEM_TYPE_LIVE"
  data["feed"]["exchanges"][ref_mea]["products"] = {}
  data["feed"]["exchanges"][ref_mea]["products"]["norms"] = []
  data["feed"]["exchanges"][ref_mea]["websocket"] = {"num_workers": 1}
  data["feed"]["exchanges"][ref_mea]["recipe"] = get_recipe(ref_mea)

  trade_exchange = parse_unique_symbol(list(strat['products'].values())[0]["trade_symbol"])[1]
  data["order"]["exchanges"] = {}
  data["order"]["exchanges"][trade_exchange] = {}
  data["order"]["exchanges"][trade_exchange]["mea"] = trade_mea
  data["order"]["exchanges"][trade_exchange]["type"] = "ORDER_SYSTEM_TYPE_LIVE_OG"
  data["order"]["exchanges"][trade_exchange]["products"] = {}
  data["order"]["exchanges"][trade_exchange]["products"]["norms"] = []
  data["order"]["exchanges"][trade_exchange]["order_gateway_config"] = {
      "log_private_exchange_message": "true"
  }
  data["order"]["exchanges"][trade_exchange]["order_logger_config"] = {
      "store_parsed_message": "true"
  }
  data["order"]["exchanges"][trade_exchange]["connection_config"] = {"key_filepath": key_path}


  for strat_product in strat['products'].values():
    _, trade_exchange, norm_trade_product = parse_unique_symbol(strat_product["trade_symbol"])
    _, _, norm_ref_product = parse_unique_symbol(strat_product["ref_symbol"])

    data["feed"]["exchanges"][trade_mea]["products"]["norms"].append(norm_trade_product)
    data["feed"]["exchanges"][ref_mea]["products"]["norms"].append(norm_ref_product)
    data["order"]["exchanges"][trade_exchange]["products"]["norms"].append(norm_trade_product)

  if "rest_query_config" in strat:
    data["order"]["exchanges"][trade_exchange]["rest_query_config"] = strat["rest_query_config"]

  data["log"] = {"health_report_period_ns": 30000000000}
  data["strategy"] = {"strategy_group": strategy_group, "strategy_name": strategy_name}
  return data


def get_git_root():
  for path in pathlib.Path(__file__).resolve().parents:
    if path.joinpath('.git').is_dir():
      return path
  raise FileNotFoundError("git repo root not found.")


def get_app():
  git_root = get_git_root()
  app_relpath = "cc/appcoin2/strategy/mm_pilot/simple_mm"

  app = git_root.joinpath("bazel-bin").joinpath(app_relpath)
  if app.is_file():
    return app

  app = git_root.joinpath("../coin_binary/coin2-bazel-bin").joinpath(app_relpath)
  if app.is_file():
    return app
  raise FileNotFoundError('simple_mm not found!')


def get_strategy_config(exchange):
  config_dir = pathlib.Path('cc/experimental/xguo/pilot')
  config_dir = config_dir.joinpath(exchange)
  config_path = config_dir.joinpath('strat_config.json')
  return config_path


def gen_app_config(strat_config_path):
  config = json.loads(strat_config_path.read_text())
  app_config = convert_to_app_config(config)
  filename = tempfile.NamedTemporaryFile(mode="w",
                                         delete=False,
                                         suffix=".json",
                                         prefix="simple_mm.")
  filename.write(json.dumps(app_config, indent=2))
  print(json.dumps(app_config, indent=2), file=sys.stderr)
  return filename.name


def main(_):
  os.chdir(get_git_root())

  app = get_app()
  strat_config = get_strategy_config(FLAGS.exchange)
  app_config = gen_app_config(strat_config)
  cmd_line = f"{app} --driver={app_config} --config={strat_config} --logtostderr"
  if FLAGS.gdb:
    cmd_line = "gdb --args " + cmd_line

  print(cmd_line)
  #invoke.run(cmd_line)


if __name__ == '__main__':
  app.run(main)
